#include "NetStorage.h"
//#define _DEBUG_

static size_t receiver(void*   ptr,
                       size_t  size,
                       size_t  nmemb,
                       char*   buffer)
{
  int buflen = strlen(buffer);
  int len    = size * nmemb;
  if (buflen + len > NETSTORAGE_BUFFER_MAX)
    return 0;
  memcpy(buffer + buflen, (char*)ptr, len);
  buffer[buflen + len] = 0;
  return len;
}


NetStorage::NetStorage(string proxy)
: curl(0)
{
#ifdef _DEBUG_
  printf("NetStorage::NetStorage(): Called.\n");
#endif
  curl = curl_easy_init();
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiver);
  curl_easy_setopt(curl, CURLOPT_AUTOREFERER, (void*)1);
  //curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, NETSTORAGE_BUFFER_MAX);
  
  set_proxy(proxy);
}


NetStorage::~NetStorage()
{
#ifdef _DEBUG_
  printf("NetStorage::~NetStorage(): Called.\n");
#endif
  curl_easy_cleanup(curl);
}


void NetStorage::set_baseurl(string url)
{
#ifdef _DEBUG_
  printf("NetStorage::set_baseurl(): %s\n", url.c_str());
#endif
  if (url[url.length()] != '/')
    url.append("/");
  baseurl = url;
}


void NetStorage::set_proxy(string proxy)
{
#ifdef _DEBUG_
  printf("NetStorage::set_proxy(): %s\n", proxy.c_str());
#endif
  curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str());
  //curl_easy_setopt(curl, CURLOPT_PROXYPORT, port);
  //curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
  //curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
}


int NetStorage::find_book(Book* search, vector<Book*>& results)
{
#ifdef _DEBUG_
  printf("NetStorage::find_book(): %s\n", search->get_title().c_str());
#endif
  // Generate a proper URL for the request.
  string url = baseurl;
  if (search->get_author() != "")
    url.append("author=" + search->get_author() + "&");
  if (search->get_title() != "")
    url.append("title=" + search->get_title());
  
  // Request and receive the book from the server.
  char received[NETSTORAGE_BUFFER_MAX];
  memset(&received, 0, sizeof(received));
  int err = get_url(url, received);
  if (err != 0)
    return NETSTORAGE_ERROR_LIBCURL;  //FIXME: Be more specific.
  
  // Check for server errors.
  if (strcmp(received, "Error 001:") == 0)
    return NETSTORAGE_ERROR_MISSING_FIELDS;
  if (strcmp(received, "Error 002:") == 0
    || strcmp(received, "Error 003:") == 0)
    return NETSTORAGE_ERROR_SERVER_ERROR;
  
  //FIXME: Parse XML.
  {
    Book* book = new Book;
    results.push_back(book);
  }
  
  return 0;
}


int NetStorage::get_url(string url, char* buffer)
{
#ifdef _DEBUG_
  printf("NetStorage::get_url(): %s\n", url.c_str());
#endif
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, buffer);
  curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
  return curl_easy_perform(curl);
}
